/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.araujogrosz.fractalcore;

/**
 *
 * @author renatogrosz@gmail.com
 */
public class CalcFract implements Zoonable, Calcable{

    private int imageSize = 20;
    private double vetorSize = 4;
    private int iterations = 100;
    private double startX = -2;
    private double startY = -2;
    private double step = vetorSize / imageSize;    
    private FractalPrinter printer;

    public void setIterations(int iterations) {
        this.iterations = iterations;
    }

    public int getImageSize(){
        return this.imageSize;
    }
    
    public CalcFract(double x, double y, int imageSize, double vetorSize){
        this.startX = x;
        this.startY = y;
        this.imageSize = imageSize;
        this.vetorSize = vetorSize;                
        this.step = this.vetorSize / this.imageSize;
    }
    public CalcFract(int imageSize) {
        this.imageSize = imageSize;
        this.vetorSize = 4;

        this.startX = - 2;
        this.startY = - 2;                

        this.step = this.vetorSize / this.imageSize;
    }
    

    public void setPrinter(FractalPrinter printer) {
        this.printer = printer;
    }

    @Override
    public void zoom(int x, int y, double fator) {
        
        double px = x * step + startX;
        double py = y * step + startY;
        
        double dx = px - startX;
        double dy = py - startY;
        
        dx = dx / fator;
        dy = dy / fator;
        
        startX = px - dx;
        startY = py - dy;
        
        
        step = step / fator;
        vetorSize = vetorSize / fator;       
        
    }

    @Override
    public void calc() {
        double px, py;        
        for (int y = 0; y<imageSize; y++) {
            py = startY + y*step;
            
            for (int x = 0; x < imageSize; x += 1) {
                px = startX + x*step;
                
                double zr = 0;
                double zi = 0;

                double cr = px;
                double ci = py;

                zr = zr + cr;
                zi = zi + ci;


                double dReal = zr * zr;
                double dImag = zi * zi;

                boolean stay = (dReal + dImag) <= 4;

                int count = 0;
                if (!stay) {
                    this.printer.paintOut(x, y);
                }

                while (stay) {
                    if (count < iterations) {
                        double real = zr * zr - zi * zi + cr;
                        double imag = 2 * zi * zr + ci;

                        zr = real;
                        zi = imag;

                        dReal = real * real;
                        dImag = imag * imag;


                        stay = (dReal + dImag) <= 4;
                        if (!stay) {
                            this.printer.paint(count, x, y);
                        }
                        count += 1;
                    } else {
                        this.printer.paint(x, y);
                        stay = false;
                    }
                }
                //x += 1;
            }            
            this.printer.paint();
        }

    }
}
